# 导入functools.wraps，这是一个装饰器，用于在创建装饰器时保留被装饰函数的元信息（如函数名、文档字符串）
from functools import wraps
# 导入我们的数据库管理器单例
from utils.db_manager import db_manager

def format_raw_sql_results(func):
    """装饰器：将原生SQL查询结果（Row对象列表）自动转换为字典列表。"""
    # @wraps(func)确保wrapper函数看起来像被装饰的func函数
    @wraps(func)
    def wrapper(*args, **kwargs):
        # 首先，正常调用被装饰的函数（例如，repository中的一个方法）
        results = func(*args, **kwargs)
        
        # 如果查询结果为空，直接返回一个空列表
        if not results:
            return []
        
        # SQLAlchemy 2.0+ 的Row对象有一个._mapping属性，它是一个类字典对象
        # 我们遍历结果列表，将每个Row对象转换为真正的Python字典
        return [dict(row._mapping) for row in results]
    
    # 返回包装后的函数
    return wrapper

def transactional(func):
    """
    装饰器：为业务逻辑方法提供自动的事务管理。
    应用此装饰器的方法将自动获得一个数据库会话(session)，并在方法执行完毕后自动提交或回滚。
    """
    @wraps(func)
    def wrapper(*args, **kwargs):
        # 使用我们之前在DatabaseManager中定义的session_scope上下文管理器
        # 'with'语句会启动一个事务
        with db_manager.session_scope() as session:
            # 将获取到的session对象通过关键字参数'session'传递给被装饰的函数
            # 例如，调用service.create_user(user_data)会变成调用service.create_user(user_data, session=session)
            # args[0]通常是被装饰方法所属的实例（即'self'）
            result = func(*args, session=session, **kwargs)
            # 'with'语句结束时，session_scope会根据执行情况自动提交或回滚
            return result
    return wrapper